package gobelinmaker.server;

import java.util.concurrent.atomic.AtomicLong;

/**
 * Motorvezérlő alaposztálya.
 *
 * @author imruf84
 */
public abstract class MotorControl {

    /**
     * Jelenlegi állás.
     */
    protected final AtomicLong currentSteps = new AtomicLong();
    /**
     * Vízszintes lépésköz mikrolépésekben.
     */
    protected final AtomicLong currentMicroSteps = new AtomicLong();
    /**
     * Motor azonosítója.
     */
    private final String motorID;
    /**
     * Legutolsó lépés.
     */
    private final AtomicLong lastSteps = new AtomicLong();
    /**
     * Irány.
     */
    private final long direction;

    /**
     * Konstruktor.
     *
     * @param ID motor azonosítója
     * @param direction irány
     */
    public MotorControl(String ID, long direction) {
        this.motorID = ID;
        this.direction = direction;
    }

    /**
     * Léptetés.
     *
     * @param steps lépészám
     */
    public void doSteps(long steps) {

        // Legutolsó lépés tárolása.
        synchronized (this.lastSteps) {
            this.lastSteps.set(steps);
        }

        // Ha nincs lépés akkor kilépünk.
        if (0 == steps) {
            return;
        }

        // Lépésszámok tárolása.
        setSteps(this.currentSteps.addAndGet(steps));

    }

    /**
     * Lépések tárolása.
     *
     * @param steps lépések száma
     */
    public void setSteps(long steps) {

        // Lépésszámok frissítése.
        synchronized (this.currentSteps) {
            this.currentSteps.set(steps);
        }

        // Mikrolépésszámok frissítése.
        synchronized (this.currentMicroSteps) {
            this.currentMicroSteps.set(this.getCurrentSteps() * this.getMicroStepSize());
        }
    }

    /**
     * Legutolsó lépés végrehajtása.
     */
    public void doLastSteps() {
        synchronized (this.lastSteps) {
            this.doSteps(this.lastSteps.get());
        }
    }

    /**
     * Legutolsó lépések számának a lekérdezése.
     *
     * @return legutolsó lépések száma
     */
    public long getLastSteps() {
        return this.lastSteps.get();
    }

    /**
     * Irány lekérdezése.
     *
     * @return irány
     */
    public long getDirection() {
        return this.direction;
    }

    /**
     * Mikrolépés/lépés számának a lekérdezése.
     *
     * @return egy lépés alatti mikrolépések száma
     */
    public abstract long getMicroStepSize();

    /**
     * Jelenlegi lépésszám lekérdezése.
     *
     * @return lépésszám
     */
    public long getCurrentSteps() {
        return this.currentSteps.get();
    }

    /**
     * Jelenlegi mikrolépések számának a lekérdezése.
     *
     * @return jelenlegi mikrolépések száma
     */
    public long getCurrentMicroSteps() {
        return this.currentMicroSteps.get();
    }

    /**
     * Motor azonosítójának a lekérdezése.
     *
     * @return motor azonosítója
     */
    public String getMotorID() {
        return motorID;
    }

    /**
     * Motor leállítása.
     */
    public abstract void stop();
}
